/*
 * 
 * Copyright 2010 David H Pollack
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 * 
 * 
 */

package fantasy;

import fantasy.StatCategory;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Pattern;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.Query;
import javax.jdo.Transaction;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import net.oauth.OAuthException;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.simpleyql.Api;
import com.simpleyql.ApiFactory;
import com.simpleyql.QueryResult;

public class FiveToolsServlet extends HttpServlet {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 3058472473577849508L;

	public void doGet(HttpServletRequest req, HttpServletResponse resp)
		throws IOException {
		
        // Stuff to get baseurl
		Properties props = new Properties();
        props.load(this.getClass().getClassLoader().getResourceAsStream("fantasy.properties"));
        String baseurl = props.getProperty("application.baseurl");

        // Get Google's User
        UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();

        // Initiate Persistence Manager for Yahoo OAuth information
		PersistenceManager pm = PMF.get().getPersistenceManager();
		



		YahooApiQuery yahoo = new YahooApiQuery();
		
		yahoo.setUser(user.getNickname());
		
		String tmp = yahoo.query("http://fantasysports.yahooapis.com/fantasy/v2/league/238.l.145036/settings");
		
		resp.getWriter().println(tmp);
		
		try {
			
			//Initialize LeagueSettings variable
			
			
			resp.getWriter().println("Reading XML\n");

			InputSource is = new InputSource(new StringReader(tmp));
			
			Document response = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);

			resp.getWriter().println("Creating XPath Factory\n");
			XPathFactory factory = XPathFactory.newInstance();

			XPath xPath=factory.newXPath();


			Integer league_id 	= Integer.parseInt((String)xPath.evaluate("//league_id", response, XPathConstants.STRING));
			
			String league_name = (String)xPath.evaluate("//league/name", response, XPathConstants.STRING);
			
			String league_url = (String)xPath.evaluate("//league/url", response, XPathConstants.STRING);
			
			String league_draft_status = (String)xPath.evaluate("//league/draft_status", response, XPathConstants.STRING);
			
			Integer league_num_teams = Integer.parseInt((String)xPath.evaluate("//num_teams", response, XPathConstants.STRING));
			
			String league_update_timestamp = (String)xPath.evaluate("//league_update_timestamp", response, XPathConstants.STRING);
			
			String league_draft_type = (String)xPath.evaluate("//draft_type", response, XPathConstants.STRING);
			
			String league_scoring_type = (String)xPath.evaluate("//scoring_type", response, XPathConstants.STRING);
			
			Integer league_uses_playoff = Integer.parseInt((String)xPath.evaluate("//uses_playoff", response, XPathConstants.STRING));
			
			Integer league_uses_faab = Integer.parseInt((String)xPath.evaluate("//uses_faab", response, XPathConstants.STRING));
			
			// Game Key Finder
			
			String league_key = (String)xPath.evaluate("//league_key", response, XPathConstants.STRING);
			resp.getWriter().println("League Key: " + league_key);
			String regex = "\\.";

			Pattern numSplit = Pattern.compile(regex);
			
			String[] m = numSplit.split(league_key);
			
			Integer game_key = Integer.parseInt(m[0]);
			
			String game_type = null;

			resp.getWriter().println("Game Key: " + m[0] + "|" + game_key);
			
			if(game_key.equals(238)) {
				game_type = "baseball";
			}

			// Set league variables
			

			
			
			
			//Get all search Result nodes
			// Here I'm searching for the "stat" nodes within the XML.  At any level
			// Very roughly using http://java.sun.com/developer/technicalArticles/xml/validationxpath/
			// as a guide.
			
			resp.getWriter().println("Getting Result nodes\n");
			NodeList nodesRosters = (NodeList)xPath.evaluate("//settings/roster_positions/roster_position", response, XPathConstants.NODESET);

			int nodeCountRosters = nodesRosters.getLength();
			
			Set<RosterPositions> rosterpositions = new HashSet<RosterPositions>();
			
			for (int i=0; i < nodeCountRosters; i++) {

				String roster_position = (String)xPath.evaluate("position", nodesRosters.item(i), XPathConstants.STRING);

				Integer roster_position_count = Integer.parseInt((String)xPath.evaluate("count", nodesRosters.item(i), XPathConstants.STRING));
				
				RosterPositions r = new RosterPositions();
				r.setRosterPosition(roster_position);
				r.setRosterPositionCount(roster_position_count);
				
				rosterpositions.add(r);
				
			}
			
			
			//Get all search Result nodes
			// Here I'm searching for the "stat" nodes within the XML.  At any level
			// Very roughly using http://java.sun.com/developer/technicalArticles/xml/validationxpath/
			// as a guide.
			
			resp.getWriter().println("Getting Result nodes\n");
			NodeList nodesStats = (NodeList)xPath.evaluate("//settings/stat_categories/stats/stat", response, XPathConstants.NODESET);

			int nodeCountStats = nodesStats.getLength();

			resp.getWriter().println("Result Count: " + nodeCountStats + "\n");

			//iterate over search Result nodes

			Set<Key> statcategories = new HashSet<Key>();
			
			for (int i = 0; i < nodeCountStats; i++) {

			  //Get each xpath expression as a string

			  String stat_name = (String)xPath.evaluate("name", nodesStats.item(i), XPathConstants.STRING);

			  String stat_display_name = (String)xPath.evaluate("display_name", nodesStats.item(i), XPathConstants.STRING);

			  Integer stat_id = Integer.parseInt((String)xPath.evaluate("stat_id", nodesStats.item(i), XPathConstants.STRING));

			  String stat_position_type = (String)xPath.evaluate("position_type", nodesStats.item(i), XPathConstants.STRING);

			  String key_gen = game_type + "-" + stat_id.toString();
			  
			  //print out the Title, Summary, and URL for each search result

			  resp.getWriter().println("stat: " + stat_name);

			  resp.getWriter().println("display_name: " + stat_display_name);

			  resp.getWriter().println("stat_id: " + stat_id.toString());

			  resp.getWriter().println("key gen: " + key_gen );
			  
			  resp.getWriter().println("--");
			  
			  
			  Transaction tx = pm.currentTransaction();
			  
		      try {
		    	  tx.begin();

				  Key key = KeyFactory.createKey(StatCategory.class.getSimpleName(), key_gen);
				  statcategories.add(key);
				  StatCategory s;
		          try {
		        	  s = pm.getObjectById(StatCategory.class, key);
		          } catch (JDOObjectNotFoundException e) {
		              s = new StatCategory();
		              s.setKey(key);
		              s.setGameKey(game_key);
		              s.setGameType(game_type);
		              s.setStatId(stat_id);
		              s.setStatName(stat_name);
		              s.setStatDisplayName(stat_display_name);
		              s.setStatType("stat_type");
		              s.setPositionType(stat_position_type);
		              s.setStatDivisorType("divisor");
		              s.setStatDivisorNum(1);
		              
		          }

		          pm.makePersistent(s);

		          tx.commit();

		      } finally {
		          if (tx.isActive()) {
		              tx.rollback();
		          }
		      }


		      /*
			  StatCategory s = pm.getObjectById(StatCategory.class, key);
			  
			  
			  
			  StatCategory stat = new StatCategory(game_key, game_type, stat_id, stat_name,
										stat_display_name, "stat_type", stat_position_type, "divisor", 
										1);
			  
			  stat.setKey(key);
			  
			  pm.makePersistent(stat);
			  
			  */
			
		    

			}

			Transaction tx2 = pm.currentTransaction();
			try {
		    	tx2.begin();
			    LeagueSettings league;

		        try {
		        	league = pm.getObjectById(LeagueSettings.class, league_key);
		        } catch (JDOObjectNotFoundException e) {
		        	league = new LeagueSettings();
					league.setLeagueKey(league_key);
					league.setGameKey(game_key);
					league.setGameType(game_type);
					league.setLeagueId(league_id);
					league.setLeagueName(league_name);
					league.setNumTeams(league_num_teams);
					league.setsDraftType(league_draft_type);
					league.setDraftStatus(league_draft_status);
					league.setsScoringType(league_scoring_type);
					league.setsUsesPlayoff(league_uses_playoff);
					league.setsUsesFaab(league_uses_faab);
					league.setsRosterPositionSet(rosterpositions);
					league.setStats(statcategories);
		        }
		    	pm.makePersistent(league);

		    	tx2.commit();

		    } finally {
		    	if (tx2.isActive()) {
		    		tx2.rollback();
		    	}
		    }

		} catch (SAXException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParserConfigurationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (XPathExpressionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	      

	    
		
	}

}
